package com.yuyou.fn.educational.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.Threads;
import com.yuyou.fn.educational.entity.Campus;
import com.yuyou.fn.educational.mapper.CampusMapper;
import com.yuyou.fn.educational.vo.CampusCondVo;
import com.yuyou.fn.educational.vo.CampusSimpleVo;
import com.yuyou.fn.platform.mapper.SysUserMapper;
import com.yuyou.fn.platform.service.IAreaTeamService;
import com.yuyou.fn.platform.service.IBusTeamService;
import com.yuyou.fn.educational.service.ICampusService;
import com.yuyou.fn.educational.service.IRoomService;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.CriteriaUtils;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.educational.vo.CampusQueryVo;
import com.yuyou.fn.educational.vo.CampusSaveOrUpdateVo;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Campus 表数据服务层接口实现类
 */
@Service
public class CampusServiceImpl extends SuperServiceImpl<CampusMapper, Campus, Long> implements ICampusService {


    @Resource
    private IRoomService roomService;

    @Resource
    private IAreaTeamService areaTeamService;

    @Resource
    private IBusTeamService busTeamService;


    @Override
    public Page<Campus> findCampusByQueryForPage(CampusQueryVo campusQueryVo, int pageNo, int pageSize) {
        Example<Campus> example = Campus.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();
        CriteriaUtils.fillCondition(criteria, campusQueryVo);

        return findPageByExample(example, pageNo, pageSize);
    }

    @Override
    public void saveOrUpdateCampus(CampusSaveOrUpdateVo campusSaveOrUpdateVo) {

        final Campus campus = new Campus();
        BeanUtils.copyProperties(campus, campusSaveOrUpdateVo);

        fillExtraData(campus);


        if (campus.getCampusId() == null) {
            campus.setCreateTime(TimeUtils.now());
            campus.setUpdateTime(TimeUtils.now());
            insertSelective(campus);
        } else {
            campus.setUpdateTime(TimeUtils.now());
            updateSelectiveById(campus);
        }
        Threads.dispatch(new Runnable() {
            @Override
            public void run() {
                updateGeoLocation(campus.getCampusId());
            }
        });

    }

    private void updateGeoLocation(Long campusId) {
        Campus campus = findById(campusId);
        Campus update = new Campus();
        update.setCampusId(campusId);
        update.setGeoLocation(fetchLatitudeAndLongitudeByAddressCity(campus.getAddress(),campus.getCity()));
        updateSelectiveById(update);
    }

    private void fillExtraData(Campus campus) {

        if (campus.getAreaTeamId() != null) {
            campus.setAreaTeamName(areaTeamService.findTeamNameById(campus.getAreaTeamId()));
        } else {
            campus.setAreaTeamId(0l);
            campus.setAreaTeamName("");
        }

        if (campus.getBusTeamId() != null) {
            campus.setBusTeamName(busTeamService.findTeamNameById(campus.getBusTeamId()));
        } else {
            campus.setBusTeamId(0l);
            campus.setBusTeamName("");
        }


    }

    private static String  fetchLatitudeAndLongitudeByAddressCity(String address , String city){


        try {
            URL url = new URL("http://api.map.baidu.com/geocoder/v2/?output=json&address=" + URLEncoder.encode(address,"utf-8") + "&city=" + URLEncoder.encode(city,"utf-8") + "&ak=9918662ae4b6a7bda5e9d0a6d0d09b47") ;
            URLConnection urlConnection = url.openConnection();
            InputStream inputStream = urlConnection.getInputStream();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024 );
            byte[] buf = new byte[1024] ;
            int len = 0 ;
            while((len = inputStream.read(buf)) != -1 ){
                outputStream.write(buf,0 , len );
            }
            inputStream.close();

            JSONObject jsonObject = JSONObject.parseObject(new String(outputStream.toByteArray(), "utf-8"));

            if(jsonObject.getInteger("status") == 1 ){
                throw new BusException("地址无法获取到经纬度");
            }
            JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");

            return location.getString("lng") + " " + location.getString("lat") ;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Transactional
    @Override
    public void deleteCampus(Long campusId) {
        roomService.deleteByCampusId(campusId);
        deleteById(campusId);

    }

    @Override
    public String findCampusNameByCampusId(Long campusId){
        Example<Campus> example = Campus.createExample();
        example.selectProperties("campusName");
        example.createCriteria().andEqualTo("campusId",campusId);
        Campus campus = findOneByExample(example);

        return campus == null ? StringUtils.EMPTY : campus.getCampusName() ;
    }

    @Override
    public List<Campus> findCampusByCityOrderByDistrict(String city) {
        Example<Campus> example=Campus.createExample();
        Example.Criteria criteria=example.createCriteria();
        criteria.andEqualTo("city",city);
        example.orderBy("district");
        return findListByExample(example);
    }

    @Override
    public List< CampusCondVo> findCampusCond(String city) {
        List<Campus> campusList=this.findCampusByCityOrderByDistrict(city);
        String checkDistrict="";
        int campusListSize=campusList.size();
        if(campusListSize>0){
            checkDistrict=campusList.get(0).getDistrict();
        }else {
            throw new BusException("暂无校区");
        }
        List<CampusCondVo> campusCondVoList=new ArrayList<CampusCondVo>();
        int record=0;
        String preffx=",";
        for (int i=0;i<campusListSize;i++){
            if(i==campusListSize-1) preffx="";
            Campus campus=campusList.get(i);
            if(i==0){
                CampusCondVo campusCondVo=new CampusCondVo();
                campusCondVo.setDistrict(campus.getDistrict());

                campusCondVo.setDistrictIds(campusCondVo.getDistrictIds()==null?campus.getCampusId().toString():campusCondVo.getDistrictIds()+preffx+campus.getCampusId());
                List<CampusSimpleVo> campusList1=new ArrayList<CampusSimpleVo>();
                CampusSimpleVo campusSimpleVo=new CampusSimpleVo();
                campusSimpleVo.setCampusId(campus.getCampusId());
                campusSimpleVo.setCampusName(campus.getCampusName());
                campusList1.add(campusSimpleVo);
                campusCondVo.setCampusSimpleVoList(campusList1);
                campusCondVoList.add(campusCondVo);
            }else{
                if(!checkDistrict.equals(campus.getDistrict())){
                    CampusCondVo campusCondVo=new CampusCondVo();
                    campusCondVo.setDistrict(campus.getDistrict());
                    campusCondVo.setDistrictIds(campusCondVo.getDistrictIds()==null?campus.getCampusId().toString():campusCondVo.getDistrictIds()+preffx+campus.getCampusId());
                    List<CampusSimpleVo> campusList1=new ArrayList<CampusSimpleVo>();
                    CampusSimpleVo campusSimpleVo=new CampusSimpleVo();
                    campusSimpleVo.setCampusId(campus.getCampusId());
                    campusSimpleVo.setCampusName(campus.getCampusName());
                    campusList1.add(campusSimpleVo);
                    campusCondVo.setCampusSimpleVoList(campusList1);
                    campusCondVoList.add(campusCondVo);
                    checkDistrict=campus.getDistrict();
                    record++;
                }else {
                    CampusCondVo campusCondVo=campusCondVoList.get(record);
                    campusCondVo.setDistrictIds(campusCondVo.getDistrictIds()==null?campus.getCampusId().toString():campusCondVo.getDistrictIds()+preffx+campus.getCampusId());
                    List<CampusSimpleVo> campusList1=campusCondVo.getCampusSimpleVoList();
                    CampusSimpleVo campusSimpleVo=new CampusSimpleVo();
                    campusSimpleVo.setCampusId(campus.getCampusId());
                    campusSimpleVo.setCampusName(campus.getCampusName());
                    campusList1.add(campusSimpleVo);
                    //campusCondVo.setCampusList(campusList1);
                }
            }

        }

        return campusCondVoList;
    }

    @Override
    public List<Campus> findCampusByCity(String city) {
        return this.findCampusByCityOrderByDistrict(city);
    }
}